package com.example.service.impl;

import com.example.mapper.GroupMapper;
import com.example.service.GroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.IntStream;

@Service
public class GroupServiceImpl implements GroupService {

    @Autowired
    private GroupMapper groupMapper;

    // 格式化平均分数的 DecimalFormat 实例，设为 static 以避免重复创建
    private static final DecimalFormat df = new DecimalFormat("0");
    private static final Logger logger = LoggerFactory.getLogger(GroupServiceImpl.class);

    @Override
    public List<Map<String, Object>> getStudentScores(Map<String, Object> paramMap) {
        List<Map<String, Object>> students;
        try {
            // 从数据库获取学生成绩，使用传入的 paramMap 作为参数
            students = groupMapper.getStudentScores(paramMap);
        } catch (Exception e) {
            logger.error("获取学生成绩时发生异常", e);
            return Collections.emptyList();
        }
        if (students == null) {
            return Collections.emptyList();
        }

        // 按照成绩排序
        students.sort(Comparator.comparingDouble(s -> Double.parseDouble(s.get("score").toString())));

        // 初始化 5 个组
        List<List<Map<String, Object>>> groups = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            groups.add(new ArrayList<>());
        }

        // 分组逻辑
        int index = 0;
        for (Map<String, Object> student : students) {
            int groupNumber = index % 5 + 1; // 生成组号，从1到5
            student.put("group_number", groupNumber); // 在学生的Map中添加组号
            groups.get(index % 5).add(student);
            index++;
        }

        // 将组号更新到数据库的student表中的group字段
        for (Map<String, Object> student : students) {
            try {
                long studentId = (long) student.get("student_id");
                int groupNumber = (int) student.get("group_number");
                groupMapper.updateStudentGroup(studentId, groupNumber);
            } catch (Exception e) {
                logger.error("更新学生组号时发生异常", e);
            }
        }

        // 用于存储最终结果，符合要求的格式
        List<Map<String, Object>> result = new ArrayList<>();

        // 遍历每个组
        for (int i = 0; i < groups.size(); i++) {
            List<Map<String, Object>> currentGroup = groups.get(i);
            List<String> members = new ArrayList<>();
            double totalScore = 0;
            double totalBeforeScore = 0;
            double totalDuringScore = totalBeforeScore;
            double totalAfterScore = 0;

            // 遍历当前组内的每个学生，提取名字和计算总分
            for (Map<String, Object> student : currentGroup) {
                members.add((String) student.get("student_name"));
                totalScore += Double.parseDouble(student.get("score").toString());
                totalBeforeScore += Double.parseDouble(student.get("before").toString());
                totalDuringScore += Double.parseDouble(student.get("during").toString());
                totalAfterScore += Double.parseDouble(student.get("after").toString());
            }

            Map<String, Object> groupInfo = new HashMap<>();
            // 组名从 1 开始
            groupInfo.put("name", "第" + (i + 1) + "组");
            groupInfo.put("members", members);

            // 使用 DecimalFormat 格式化平均分数，保留整数
            double averageScore = totalScore / currentGroup.size();
            groupInfo.put("score", Double.parseDouble(df.format(averageScore)));

            // 计算并添加课前、课中、课后的平均成绩
            double averageBeforeScore = totalBeforeScore / currentGroup.size();
            double averageDuringScore = totalDuringScore / currentGroup.size();
            double averageAfterScore = totalAfterScore / currentGroup.size();

            groupInfo.put("before", Double.parseDouble(df.format(averageBeforeScore)));
            groupInfo.put("during", Double.parseDouble(df.format(averageDuringScore)));
            groupInfo.put("after", Double.parseDouble(df.format(averageAfterScore)));
            result.add(groupInfo);
        }
        return result;
    }

    // 小组排名的方法
    @Override
    public Map<String, List<Object>> getGroupRanking(Map<String, Object> paramMap) {
        List<Map<String, Object>> groups;
        try {
            groups = getStudentScores(paramMap);
        } catch (Exception e) {
            logger.error("获取小组数据时发生异常", e);
            return new HashMap<>();
        }
        if (groups == null) {
            return new HashMap<>();
        }

        // 按照平均分数从高到低排序
        groups.sort((group1, group2) -> {
            double score1 = (double) group1.get("score");
            double score2 = (double) group2.get("score");
            return Double.compare(score2, score1);
        });

        List<Object> names = new ArrayList<>();
        List<Object> scores = new ArrayList<>();

        for (Map<String, Object> group : groups) {
            names.add(group.get("name"));
            scores.add(group.get("score"));
        }

        Map<String, List<Object>> ranking = new HashMap<>();
        ranking.put("name", names);
        ranking.put("score", scores);

        return ranking;
    }

    // 排名前十的学生信息
    @Override
    public Map<String, Object> getTopTenStudentScores(Map<String, Object> paramMap) {
        List<Map<String, Object>> topTenStudents;
        try {
            topTenStudents = groupMapper.getTopTenStudentScores(paramMap);
        } catch (Exception e) {
            logger.error("获取排名前十的学生信息时发生异常", e);
            return new HashMap<>();
        }
        Map<String, Object> result = new HashMap<>();
        List<String> names = new ArrayList<>();
        List<Double> scores = new ArrayList<>();
        List<Double> beforeScores = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        List<Double> duringScores = new ArrayList<>();
        List<Double> afterScores = new ArrayList<>();
        if (topTenStudents != null) {
            for (Map<String, Object> student : topTenStudents) {
                names.add((String) student.get("student_name"));
                scores.add(Double.parseDouble(student.get("score").toString()));
                beforeScores.add(Double.parseDouble(student.get("before").toString()));
                ids.add((Long) student.get("student_id"));
                duringScores.add(Double.parseDouble(student.get("during").toString()));
                afterScores.add(Double.parseDouble(student.get("after").toString()));
            }
        }

        result.put("name", names);
        result.put("score", scores);
        result.put("before", beforeScores);
        result.put("id", ids);
        result.put("during", duringScores);
        result.put("after", afterScores);

        return result;
    }
//    任务分成课前,课中,课后
@Override
public Map<String, List<Object>> getMissionStats(Map<String, Object> params) {
    List<Map<String, Object>> missionStats;
    try {
        missionStats = groupMapper.getMissionStats(params);
    } catch (Exception e) {
        logger.error("获取任务统计信息时发生异常", e);
        return Collections.emptyMap();
    }

    if (missionStats.isEmpty()) {
        return Collections.emptyMap();
    }

    final int size = missionStats.size();
    Map<String, List<Object>> formattedResult = new HashMap<>(5);

    Object[] missionArray = new Object[size];
    Object[] beforeArray = new Object[size];
    Object[] duringArray = new Object[size];
    Object[] afterArray = new Object[size];
    Object[] scoreArray = new Object[size];

    // 根据数据量决定是否使用并行处理
    if (size > 1000) { // 阈值可以根据实际情况调整
        IntStream.range(0, size).parallel().forEach(i -> {
            Map<String, Object> stat = missionStats.get(i);
            missionArray[i] = stat.get("mission");
            beforeArray[i] = stat.get("before");
            duringArray[i] = stat.get("during");
            afterArray[i] = stat.get("after");
            scoreArray[i] = stat.get("score");
        });
    } else {
        // 小数据量使用普通循环
        for (int i = 0; i < size; i++) {
            Map<String, Object> stat = missionStats.get(i);
            missionArray[i] = stat.get("mission");
            beforeArray[i] = stat.get("before");
            duringArray[i] = stat.get("during");
            afterArray[i] = stat.get("after");
            scoreArray[i] = stat.get("score");
        }
    }

    formattedResult.put("mission", Collections.unmodifiableList(Arrays.asList(missionArray)));
    formattedResult.put("before", Collections.unmodifiableList(Arrays.asList(beforeArray)));
    formattedResult.put("during", Collections.unmodifiableList(Arrays.asList(duringArray)));
    formattedResult.put("after", Collections.unmodifiableList(Arrays.asList(afterArray)));
    formattedResult.put("score", Collections.unmodifiableList(Arrays.asList(scoreArray)));

    return Collections.unmodifiableMap(formattedResult);
}

    // 统计不同组号的平均成绩，参数动态传入
    @Override
    public Map<String, List<Object>> getAverageScoreByGroup(Map<String, Object> paramMap) {
        List<Map<String, Object>> averageScores = groupMapper.getAverageScoreByGroup(paramMap);
        List<Object> scores = new ArrayList<>();
        List<Object> groups = new ArrayList<>();

        for (Map<String, Object> scoreMap : averageScores) {
            scores.add(scoreMap.get("score"));
            groups.add(scoreMap.get("group"));
        }
        Map<String, List<Object>> result = new HashMap<>();
        result.put("score", scores);
        result.put("group", groups);
        result.put("type", Collections.singletonList(averageScores));
        return result;
    }

    @Override
    public List<Map<String, Object>> getAllInteractRecords() {
        return groupMapper.getAllInteractRecords();
    }
//    小组分组
    @Override
    public Map<String, List<Object>> getMissionStatsByGroup(Map<String, Object> params) {
        List<Map<String, Object>> missionStats;
        try {
            missionStats = groupMapper.getMissionStatsByGroup(params);
        } catch (Exception e) {
            logger.error("获取任务统计信息时发生异常", e);
            return new HashMap<>();
        }
        Map<String, List<Object>> formattedResult = new HashMap<>();
        List<Object> IdsList = new ArrayList<>();
        List<Object> groupList = new ArrayList<>();
        List<Object> beforeList = new ArrayList<>();
        List<Object> duringList = new ArrayList<>();
        List<Object> afterList = new ArrayList<>();
        List<Object> scoreList = new ArrayList<>();

        for (Map<String, Object> stat : missionStats) {
            IdsList.add(extractValue(stat, "ids"));
            groupList.add(extractValue(stat, "group"));
            beforeList.add(extractValue(stat, "before"));
            duringList.add(extractValue(stat, "during"));
            afterList.add(extractValue(stat, "after"));
            scoreList.add(extractValue(stat, "score"));
        }

        formattedResult.put("ids", IdsList);
        formattedResult.put("group", groupList);
        formattedResult.put("before", beforeList);
        formattedResult.put("during", duringList);
        formattedResult.put("after", afterList);
        formattedResult.put("score", scoreList);

        return formattedResult;
    }
    @Override
    public List<Map<String, Object>> getWarningData(Map<String, Object> params) {
        try {
            List<Map<String, Object>> rawData = groupMapper.getWarningData(params);
            List<Map<String, Object>> result = new ArrayList<>();

            for (Map<String, Object> item : rawData) {
                Map<String, Object> formattedItem = new LinkedHashMap<>();
                // 设置基本字段
                formattedItem.put("category", item.get("category"));
                formattedItem.put("total_count", item.get("total_count"));
                formattedItem.put("total_students", item.get("total_students"));

                // 处理学生ID数组
                String studentId = (String) item.get("student_id");
                if (studentId != null && !studentId.isEmpty()) {
                    formattedItem.put("student_id", Arrays.asList(studentId.split(",")));
                } else {
                    formattedItem.put("student_id", new ArrayList<>());
                }

                // 处理学生姓名数组
                String studentName = (String) item.get("student_name");
                if (studentName != null && !studentName.isEmpty()) {
                    formattedItem.put("student_name", Arrays.asList(studentName.split(",")));
                } else {
                    formattedItem.put("student_name", new ArrayList<>());
                }

                // 处理出现次数数组
                String occurrenceTimes = (String) item.get("occurrence_times");
                if (occurrenceTimes != null && !occurrenceTimes.isEmpty()) {
                    formattedItem.put("occurrence_times", Arrays.asList(occurrenceTimes.split(",")));
                } else {
                    formattedItem.put("occurrence_times", new ArrayList<>());
                }

                result.add(formattedItem);
            }

            return result;
        } catch (Exception e) {
            logger.error("获取预警数据时发生异常", e);
            return new ArrayList<>();
        }
    }
    @Override
    public List<Map<String, Object>> getDuringErrorData(Map<String, Object> params) {
        return groupMapper.getDuringErrorData(params);
    }

    @Override
    public Map<String, Object> yourOriginalSqlId(Map<String, Object> params) {
        List<Map<String, Object>> list = groupMapper.yourOriginalSqlId(params);

        // 初始化结果对象
        Map<String, Object> result = new LinkedHashMap<>(); // 使用 LinkedHashMap 保持顺序
        List<Object> duringList = new ArrayList<>();
        List<Object> groupList = new ArrayList<>();
        List<Object> flowerList = new ArrayList<>();

        // 遍历原始数据，提取各字段值到对应的列表
        for (Map<String, Object> item : list) {
            duringList.add(item.get("during"));
            groupList.add(item.get("group"));
            flowerList.add(item.get("flower"));
        }

        // 将列表放入结果对象
        result.put("during", duringList);
        result.put("group", groupList);
        result.put("flower", flowerList);

        return result;
    }

    private Object extractValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value != null) {
            if (value instanceof Number) {
                return Double.parseDouble(value.toString());
            }
            return value;
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> getFaultByClassIdAndMissionType(Integer classId, String missionType) {
        return groupMapper.getFaultByClassIdAndMissionType(classId, missionType);
    }
}
